<?php
/**
 * Created by PhpStorm.
 * User: Jerry
 * Date: 3/17/2020
 * Time: 8:15 PM
 * Note: api.php
 */

namespace app\lib;

use app\lib\enum\enum_lock_cmd;
use app\lib\enum\enum_redis_key;
use app\lib\enum\enum_web_cmd;
use app\lib\model\channel_machine;

/**
 * Class api
 *
 * 所有对外 API 暴露类请继承这个，省的写 $tz 了
 *
 * @package app\lib
 */
class api extends base
{
    public int    $uid              = 0;
    public int    $account_id       = 0;
    public string $open_id          = '';
    public string $token_app        = '';
    public string $token_admin      = '';
    public int    $check_token      = 1;                    //0不解析1必须解析2传了就解析3合伙人解析
    public int    $partner_level    = 0;

    //调试模式（跳过签名）
    const DEBUG_KEY = 'YxoDxDFteECKwiwbrLvd6yL5';

    //过滤保留字段（不过滤）
    const ESCAPE_EXCLUDE = ['token_app', '__DEB__'];

    /**
     * api constructor.
     *
     * @throws \Exception
     */
    public function __construct()
    {
        parent::__construct();
        //获取token
        $this->token_app   = $this->io_unit->src_input['token_app'] ?? '';
        $this->token_admin = $this->io_unit->src_input['token_admin'] ?? '';

        //数据签名
        $debug = $this->io_unit->src_input['__DEB__'] ?? '';
        if ($debug !== self::DEBUG_KEY) {
            //verify::new()->check(1);
        }

        //入参过滤
        $this->escape($this->io_unit->src_input);

        //解析token
        $this->check_token();

    }

    /**
     * 解析token
     *
     * @throws \Exception
     */
    public function check_token()
    {
        if (0 === $this->check_token) {
            return;
        }
        if ($this->check_token == 3) {
            $this->check_token_partner();
            return;
        }

        if (empty($this->token_app)) {
            if ($this->check_token == 1) {
                $this->fail(10013);
            }
            if ($this->check_token == 2) {

                //解析地推后台
                if ($this->token_admin) {
                    $admin_token_data = token::new()->parse($this->token_admin, 'id');

                    if ($admin_token_data['status'] !== 0) {
                        $this->fail(10013);
                    }
                    $this->account_id       = (int)$admin_token_data['data']['id'];
                }
                return;
            }
        }

        $token_data = token::new()->parse($this->token_app, 'uid');

        if ($token_data['status'] !== 0) {
            $this->fail(10013);
        }

        $this->uid     = (int)$token_data['data']['uid'];
        $this->open_id = $token_data['data']['open_id'];
    }

    public function check_token_partner()
    {
        if (empty($this->token_app)) {
            $this->fail(10013);
        }
        $token_data = token::new()->parse($this->token_app, 'uid');
        if ($token_data['status'] !== 0) {
            $this->fail(10013);
        }
        $this->uid           = (int)$token_data['data']['uid'];
        $this->partner_level = (int)$token_data['data']['partner_level'];
    }

    /**
     * 过滤输入
     *
     * @param array $input_data
     */
    private function escape(array &$input_data): void
    {
        foreach ($input_data as $key => &$value) {
            if (is_array($value)) {
                $this->escape($value);
                continue;
            }

            if (in_array($key, self::ESCAPE_EXCLUDE, true)) {
                continue;
            }
            if (is_string($value)) {
                $value = htmlspecialchars($value, ENT_QUOTES | ENT_HTML5, 'UTF-8');
            }
        }
    }

}
